package edu.poly.game.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import edu.poly.game.battleship.BattleShipType;
import edu.poly.game.control.GameMode;
import edu.poly.game.util.Dimension;

/**
 * configuration class, loads game settings from external file changing values on the external file changes game setting
 * 
 * @author kevint
 * 
 */
public class Configuration {
	private int numberOfMissiles;
	private int shipsPerPlayer;
	private Dimension boardSize;
	private Map<BattleShipType, Dimension> availableShips;
	
	private static String validationConfigFileLocation = "src/edu/poly/game/config/validationMode.properties";
	private static String gameplayConfigFileLocation = "src/edu/poly/game/config/gameplayMode.properties";

	private Configuration(final int numberOfMissils, final int shipsPerPlayer,
			final Map<BattleShipType, Dimension> availableShips, final Dimension boardSize) {
		this.numberOfMissiles = numberOfMissils;
		this.shipsPerPlayer = shipsPerPlayer;
		this.availableShips = availableShips;
		this.boardSize = boardSize;
	}

	public int getNumberOfMissiles() {
		return this.numberOfMissiles;
	}

	public int getNumberOfShipsPerPlayer() {
		return this.shipsPerPlayer;
	}

	public Map<BattleShipType, Dimension> getShipConfig() {
		return Collections.unmodifiableMap(this.availableShips);
	}

	public Dimension getBoardSize() {
		return this.boardSize;
	}

	public static Configuration getConfiguration(final GameMode gameMode) {
		String fileLocation = null;
		switch(gameMode) {
			case VALIDATION:
				fileLocation = validationConfigFileLocation;
				break;
			case GAMEPLAY:
				fileLocation = gameplayConfigFileLocation;
				break;
			default:
				fileLocation = gameplayConfigFileLocation;
				break;
		}
		
		try {
			FileInputStream fileInput = new FileInputStream(new File(fileLocation));
			Properties prop = new Properties();
			prop.load(fileInput);

			return getConfiguration(prop);
		} catch (IOException io) {
			io.printStackTrace();
		} catch (NumberFormatException nfe) {
			nfe.printStackTrace();
		}
		
		return null;
	}
	
	private static Configuration getConfiguration(final Properties prop) throws NumberFormatException {
		final int numberOfMissiles = Integer.parseInt((String)prop.get("numberOfMissiles"));
		final int shipsPerPlayer = Integer.parseInt((String)prop.get("numberOfShips"));
		final int boardWidth = Integer.parseInt((String)prop.get("boardSize.width"));
		final int boardHeight = Integer.parseInt((String)prop.get("boardSize.height"));
		final Dimension boardSize = new Dimension(boardWidth, boardHeight);
		
		Map<BattleShipType, Dimension> availableShips = new HashMap<BattleShipType, Dimension>();
		int shipWidth = Integer.parseInt((String)prop.get("aircraftcarrier.width"));
		int shipHeight = Integer.parseInt((String)prop.get("aircraftcarrier.height"));
		Dimension shipDimension = new Dimension(shipWidth, shipHeight);
		BattleShipType shipType = BattleShipType.AIRCRAFTCARRIER;
		availableShips.put(shipType, shipDimension);
		
		shipWidth = Integer.parseInt((String)prop.get("destroyer.width"));
		shipHeight = Integer.parseInt((String)prop.get("destroyer.height"));
		shipDimension = new Dimension(shipWidth, shipHeight);
		shipType = BattleShipType.DESTROYER;
		availableShips.put(shipType, shipDimension);
		
		shipWidth = Integer.parseInt((String)prop.get("patrolboat.width"));
		shipHeight = Integer.parseInt((String)prop.get("patrolboat.height"));
		shipDimension = new Dimension(shipWidth, shipHeight);
		shipType = BattleShipType.PATROLBOAT;
		availableShips.put(shipType, shipDimension);
		
		return new Configuration(numberOfMissiles, shipsPerPlayer, availableShips, boardSize);
	}
}
